// tabcopymod
// methods: onClicked
// export: actionOnClicked

import {urlKeepQuery, urlKeepFragment} from "./urlmodifier.js";
import {titleModifier} from "./titlemodifier.js";

// Modify url by trimming ?#
function modifyUrl(url) {
    let urlTrim = url;

    // trim ?
    let flagTrimQuery = true;
    for (let key in urlKeepQuery) {
        if (urlTrim.match(urlKeepQuery[key])) {
            flagTrimQuery = false;
            break;
        }
    };
    urlTrim = flagTrimQuery? urlTrim.split("?")[0]: urlTrim;

    // trim #
    let flagTrimFragment = true;
    for (let key in urlKeepFragment) {
        if (urlTrim.match(urlKeepFragment[key])) {
            flagTrimFragment = false;
            break;
        }
    };
    urlTrim = flagTrimFragment ? urlTrim.split("#")[0] : urlTrim;
    return urlTrim
};

// Abbreviate url text
// if url includes ?, replace query by ...
function abbreviateUrl(url) {
    let urlAbbr = url;
    if (url.includes("?")) {
        urlAbbr = url.split("?")[0] + "?..."
    };
    return urlAbbr
};

// Modify title using modifiers
function modifyTitle(title, url) {
    // defaults to titleTrim, if no modifier matches the title
    let titleTrim = title.trim();
    let titleMod = titleTrim;
    // loop over modifiers
    for (let key in titleModifier) {
        // only process the 1st match
        if (url.match(titleModifier[key].target)) {
            // modify, trim
            titleMod = titleModifier[key].modifier(titleTrim);
            titleMod = titleMod.trim();
            // check length
            titleMod = titleMod.length>0 ? titleMod: titleTrim;
            break;
        }
    }
    return titleMod
};

/**
 * Convert one tab to text
 * @param {Tab} tab
 * @param {Object} options
 * @returns {string} text, included separators
 */
function tab1ToText(tab, options, alt) {
    let url = tab.url;
    let title = tab.title;

    // check if url is valid
    // if not, return empty string
    if ( url==undefined || url==null || url.length==0 ) {
        return ""
    };

    // modify url
    if (options["modifyurl"]) {
        url = modifyUrl(url);
    };
    let urlText = abbreviateUrl(url);

    // modify title if valid
    if (title && title.trim()) {
        if (options["modifytitle"]) {
            title = modifyTitle(title, url)
        };
    }
    // if title is not valid, use urlText
    else {
        title = urlText;
    };

    // format
    let format_key = alt === 1? "format" : "format2";
    let text;
    switch (options[format_key]) {
        case "markdown":
            text = `[${title}](${url})\n\n`;
            break;
        case "siyuan":
            text = `### ${title}\n\n[${urlText}](${url})\n\n`;
            break
        default:
            text = `${url}\n\n`;
            break;
    };

    return text
};

/**
 * Return query options given options
 * @param {string} optionsCopy options["copy"]
 * @returns {Object} query options for chrome.tabs.query
 */
function queryOptions(optionsCopy) {
    let query;
    let urlPattern = ["http://*/*", "https://*/*"];
    switch (optionsCopy) {
        case "selected":
            query = { highlighted: true, currentWindow: true, url: urlPattern };
            break;
        case "currentWindow":
            query = { currentWindow: true, url: urlPattern };
            break;
        case "allWindows":
            query = { url: urlPattern };
            break;
        default:
            query = { active: true, currentWindow: true, url: urlPattern };
            break;
    };
    return query
};

/**
 * Convert tab array to text
 * @param {Tab} tabs
 * @param {Object} options
 * @returns {Object} {text: text, ntabs: number of tabs}
 */
function tabsToText(tabs, options, alt) {
    let ntabs = 0;
    let text = "";

    // loop over tabs
    for (let tab1 of tabs) {
        let text1 = tab1ToText(tab1, options, alt);
        // append valid tabs
        if (text1.length>0) {
            ntabs = ntabs + 1;
            text = text + text1;
        };
    };
    // result
    let result = { text: text, ntabs: ntabs };
    return result
};

/**
 * Copy text to clipboard
 * ref: https://github.com/siyuan-note/siyuan-chrome/blob/main/content.js
 * @param {string} text text to copy
 * @param {number} tabId tab id where scripts will be executed
 */
function copyToClipboard(text, tabId) {
    // inject script into the tab to copy to clipboard
    chrome.scripting.executeScript({
        target: { tabId: tabId },
        args: [text],
        func: (text) => {
            let textArea = document.createElement("textarea");
            textArea.value = text;
            textArea.style.position = "fixed";
            textArea.style.left = "-999px";
            textArea.style.top = "-999px";
            document.body.appendChild(textArea);
            textArea.select();
            document.execCommand("copy");
            textArea.remove();
        }
    });
};

/**
 * Notify after done with copying.
 * Badge: text shows number of tabs copied.
 * @param {number} ntabs number of tabs
 */
function notifyCopied(ntabs, alt) {
    // change badge: text and color
    chrome.action.setBadgeText({ text: `${ntabs}` })
    let color;
    if ( ntabs > 0 ) {
        if ( alt == 1 ) {
            color = [181, 196, 177, 1];
        }
        else {
            color = [135, 206, 250, 1];
        }

    }
    else {
        color = [150, 84, 84, 1];
    }
    chrome.action.setBadgeBackgroundColor({ color: color });

    // change badge back after duration
    let timestay = 1000;
    setTimeout(
        () => {
            chrome.action.setBadgeBackgroundColor({ color: [0, 0, 0, 0] });
            chrome.action.setBadgeText({ text: "" });
        },
        timestay
    );
};

/**
 * Given options, copy tab title and url
 * @param {Object} options from storage
 */
function tabCopyMod(options, alt) {
    // query tabs
    let query = queryOptions(options["tabs"]);
    chrome.tabs.query(
        query,
        (tabs) => {
            // convert tabs to text
            let result = tabsToText(tabs, options, alt);
            if ( result.ntabs > 0) {
                // copy, notify
                copyToClipboard(result.text, tabs[0].id);
                notifyCopied(result.ntabs, alt);
            } else {
                notifyCopied(0);
            }
        }
    );
};

/**
 * Copy tabs when clicking on the extension icon
 */
export function actionOnClicked() {
    let clickTimer = null;
    let clickCount = 0;

    chrome.action.onClicked.addListener((tab) => {
        clickCount++;

        if (clickTimer === null) {
            clickTimer = setTimeout(() => {
                if (clickCount === 1) {
                    // single click, use format
                    chrome.storage.local.get(
                        ["tabs", "format", "format2", "modifytitle", "modifyurl"],
                        (result) => tabCopyMod(result, 1)
                    );
                } else {
                    // double click, use format2
                    chrome.storage.local.get(
                        ["tabs", "format", "format2", "modifytitle", "modifyurl"],
                        (result) => tabCopyMod(result, 2)
                    );
                }
                clickCount = 0;
                clickTimer = null;
            }, 300); // 300ms delay for double click
        }
    });
};